home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / ARTIFACT.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  9KB  |  366 lines

  1. /*    SCCS Id: @(#)artifact.c    3.0    88/07/27
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6.  
  7. #ifdef NAMED_ITEMS
  8.  
  9. #include "artifact.h"
  10.  
  11. #ifndef OVLB
  12.  
  13. STATIC_DCL const struct artifact artilist[];
  14.  
  15. #else /* OVLB */
  16.  
  17. /* the artifacts (currently weapons only) */
  18. STATIC_OVL const struct artifact NEARDATA artilist[] = {
  19.  
  20. #define        NO_ATTK    { 0, 0, 0, 0 }
  21.  
  22. { LONG_SWORD,     "Excalibur",    (SPFX_NOGEN | SPFX_SEEK | SPFX_DEFN |
  23.                                 SPFX_SEARCH), 0,
  24.   { 0, AD_PHYS, 5, 10 }, { 0, AD_DRLI, 0, 0}, A_LAW, 'K' },
  25.  
  26. { KATANA,     "Snickersnee",    SPFX_RESTR, 0,
  27.   { 0, AD_PHYS, 0, 8 }, NO_ATTK, A_LAW, 'S' },
  28.  
  29. /*    Ah, never shall I forget the cry, 
  30.  *        or the shriek that shrieked he,
  31.  *    As I gnashed my teeth, and from my sheath
  32.  *        I drew my Snickersnee!
  33.  *
  34.  *        --Koko, Lord high executioner of Titipu
  35.  *          (From Sir W.S. Gilbert's "The Mikado")
  36.  */
  37.  
  38. { AXE,         "Cleaver",    SPFX_RESTR, 0,
  39.   { 0, AD_PHYS, 3, 12 }, NO_ATTK, A_CHAOS, 0 },
  40.  
  41. #ifdef TOLKIEN
  42. { ORCISH_DAGGER, "Grimtooth",    SPFX_RESTR, 0,
  43.   { 0, AD_PHYS, 2, 6 }, NO_ATTK, A_CHAOS, 0 },
  44. #else
  45. { DAGGER,     "Grimtooth",    SPFX_RESTR, 0,
  46.   { 0, AD_PHYS, 2, 6 }, NO_ATTK, A_CHAOS, 0 },
  47. #endif
  48.  
  49. /*  Special purpose swords - various types */
  50.  
  51. { TWO_HANDED_SWORD, "Orcrist",    SPFX_DFLAG2, M2_ORC,
  52.   { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 'E' },
  53.  
  54. #ifdef TOLKIEN
  55. { ELVEN_DAGGER,     "Sting",    (SPFX_WARN | SPFX_DFLAG2), M2_ORC,
  56.   { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },
  57. #else
  58. { DAGGER,     "Sting",    (SPFX_WARN | SPFX_DFLAG2), M2_ORC,
  59.   { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },
  60. #endif
  61.  
  62. { LONG_SWORD,     "Frost Brand", (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN), 0,
  63.   { 0, AD_COLD, 5, 0 }, { 0, AD_COLD, 0, 0 }, A_NEUTRAL, 0 },
  64.  
  65. { LONG_SWORD,     "Fire Brand",    (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN), 0,
  66.   { 0, AD_FIRE, 5, 0 }, { 0, AD_FIRE, 0, 0 }, A_NEUTRAL, 0 },
  67.  
  68. /* Stormbringer only has a 2 because it can drain a level, providing 8 more */
  69. { BROADSWORD,     "Stormbringer", (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN |
  70.                                 SPFX_DRLI), 0,
  71.   { 0, AD_DRLI, 5, 2 }, { 0, AD_DRLI, 0, 0 }, A_CHAOS, 0 },
  72.  
  73. { LONG_SWORD,     "Sunsword",    (SPFX_RESTR | SPFX_DFLAG2), M2_UNDEAD,
  74.   { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },
  75.  
  76. { BROADSWORD,     "Dragonbane",    (SPFX_RESTR | SPFX_DCLAS), S_DRAGON,
  77.   { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_NEUTRAL, 0 },
  78.  
  79. { LONG_SWORD,     "Demonbane",    (SPFX_RESTR | SPFX_DFLAG2), M2_DEMON,
  80.   { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },
  81.  
  82. /* A silver weapon would be appropriate, if we had one. */
  83. { LONG_SWORD,     "Werebane",    (SPFX_RESTR | SPFX_DFLAG2), M2_WERE,
  84.   { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },
  85.  
  86. { LONG_SWORD,     "Giantslayer", (SPFX_RESTR | SPFX_DFLAG2), M2_GIANT,
  87.   { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_NEUTRAL, 0 },
  88.  
  89. /* Another interesting weapon would be the dwarven hammer or axe with the
  90.  * boomerang-like power of returning to the wielder's hand, if the code
  91.  * were written to add such an ability.
  92.  */
  93. { WAR_HAMMER, "Ogresmasher",    (SPFX_RESTR | SPFX_DCLAS), S_OGRE,
  94.   { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },
  95.  
  96. { WAR_HAMMER, "Mjollnir",    (SPFX_RESTR | SPFX_ATTK),  0,
  97.   { 0, AD_ELEC, 5, 24 }, NO_ATTK, A_LAW, 'V' }, /* Mjo:llnir */
  98.  
  99. { MORNING_STAR,     "Trollsbane", (SPFX_RESTR | SPFX_DCLAS), S_TROLL,
  100.   { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },
  101.  
  102. /*    ARRAY TERMINATOR    */
  103. { 0,  "", 0, 0, NO_ATTK, NO_ATTK, 0, 0 }
  104. };
  105.  
  106. const int artifact_num = SIZE(artilist);
  107.  
  108. /* this array gets saved / restored - thus not static */
  109. boolean artiexist[SIZE(artilist)];
  110.  
  111. #endif /* OVLB */
  112.  
  113. STATIC_DCL const struct artifact *FDECL(get_artifact, (struct obj *));
  114. STATIC_DCL int FDECL(spec_applies, (const struct artifact *, struct permonst *));
  115.  
  116. #ifdef OVLB
  117.  
  118. /* zero out the artifact exist list */
  119. void
  120. init_exists()
  121. {
  122.     int i;
  123.  
  124.     for(i = 0; i < SIZE(artilist); i++)
  125.         artiexist[i] = 0;
  126. }
  127.  
  128. void
  129. mkartifact(otmp1)
  130. struct obj **otmp1;
  131. {
  132.     register const struct artifact *artif;
  133.     register struct obj *otmp = *otmp1;
  134.     register int n = 0, m;
  135.  
  136.     for(artif = artilist,m = 0; artif->otyp; artif++,m++)
  137.         if(otmp->otyp == artif->otyp && !(artif->spfx & SPFX_NOGEN) &&
  138.            !artiexist[m]) n++;
  139.  
  140.     if (n) {
  141.         n = rnd(n);
  142.         for(artif = artilist,m = 0; artif->otyp && n > 0; ) {
  143.             if(otmp->otyp == artif->otyp && !(artif->spfx & SPFX_NOGEN) &&
  144.                !artiexist[m]) n--;
  145.             if (n > 0) {
  146.             artif++;
  147.             m++;
  148.             }
  149.         }
  150.  
  151.         if(artif->otyp) {
  152.             *otmp1 = oname(otmp, artif->name, 0);
  153.             artiexist[m] = TRUE;
  154.         }
  155.     }
  156. }
  157.  
  158. #endif /* OVLB */
  159. #ifdef OVL0
  160.  
  161. STATIC_OVL const struct artifact *
  162. get_artifact(otmp)
  163. struct obj *otmp;
  164. {
  165.     register const struct artifact *artif;
  166.  
  167.     if(otmp)
  168.         if(strlen(ONAME(otmp)))
  169.         for(artif = artilist; artif->otyp; artif++)
  170.             if(artif->otyp == otmp->otyp &&
  171.                !strcmp(ONAME(otmp), artif->name))
  172.                 return artif;
  173.     return((struct artifact *)0);
  174. }
  175.  
  176. #endif /* OVL0 */
  177. #ifdef OVL2
  178.  
  179. boolean
  180. is_artifact(otmp)
  181. struct obj *otmp;
  182. {
  183.     return(get_artifact(otmp) != (struct artifact *)0);
  184. }
  185.  
  186. #endif /* OVL2 */
  187. #ifdef OVLB
  188. boolean
  189. exist_artifact(otmp, name)
  190. register struct obj *otmp;
  191. register const char *name;
  192. {
  193.     register const struct artifact *artif;
  194.     register boolean *arex;
  195.  
  196.     if(otmp && strlen(name))
  197.         for(artif = artilist,arex = artiexist; artif->otyp; artif++,arex++)
  198.         if(artif->otyp == otmp->otyp &&
  199.            !strcmp(name, artif->name) &&
  200.            *arex)
  201.             return TRUE;
  202.     return FALSE;
  203. }
  204.  
  205. void
  206. artifact_exists(otmp, name, mod)
  207. register struct obj *otmp;
  208. register const char *name;
  209. register boolean mod;
  210. {
  211.     register const struct artifact *artif;
  212.     register boolean *arex;
  213.  
  214.     if(otmp && strlen(name))
  215.         for(artif = artilist,arex = artiexist; artif->otyp; artif++,arex++)
  216.         if(artif->otyp == otmp->otyp &&
  217.            !strcmp(name, artif->name))
  218.             *arex = mod;
  219.     return;
  220. }
  221.  
  222. #endif /* OVLB */
  223. #ifdef OVL0
  224.  
  225. boolean
  226. spec_ability(otmp, abil)
  227. struct obj *otmp;
  228. unsigned abil;
  229. {
  230.     const struct artifact *arti = get_artifact(otmp);
  231.     
  232.     return(arti && (arti->spfx & abil));
  233. }
  234.  
  235. #endif /* OVL0 */
  236. #ifdef OVLB
  237.  
  238. int
  239. restr_name(otmp, name)    /* returns 1 if name is restricted for otmp->otyp */
  240. register struct obj *otmp;
  241. register char    *name;
  242. {
  243.     register const struct artifact *artif;
  244.  
  245.     if(!strlen(name)) return(0);
  246.  
  247.     for(artif = artilist; artif->otyp; artif++)
  248.         if(artif->otyp == otmp->otyp)
  249.         if(artif->spfx & (SPFX_NOGEN | SPFX_RESTR))
  250.             if(!strcmp(artif->name, name)) return(1);
  251.  
  252.     return(0);
  253. }
  254.  
  255. # if defined(THEOLOGY) && defined(ALTARS)
  256. struct obj *
  257. mk_aligned_artifact(align)
  258. unsigned align;
  259. {
  260.     register const struct artifact *artif;
  261.     register struct obj *otmp;
  262.     register int n = 0, m;
  263.  
  264.     for(artif = artilist,m = 0; artif->otyp; artif++,m++)
  265.         if(align == artif->align && !(artif->spfx & SPFX_NOGEN) && !artiexist[m])
  266.         if (pl_character[0] == artif->class) {
  267.             n = 0;
  268.             break;
  269.         } else n++;
  270.     if (n) {
  271.         n = rnd(n);
  272.         for(artif = artilist,m = 0; artif->otyp && n > 0; ) {
  273.             if(align == artif->align && !(artif->spfx & SPFX_NOGEN) && !artiexist[m])
  274.             n--;
  275.             if (n > 0) {
  276.             artif++;
  277.             m++;
  278.             }
  279.         }
  280.     }
  281.     if(artif->otyp) {
  282.         otmp = mksobj((int)artif->otyp, FALSE);
  283.         otmp = oname(otmp, artif->name, 0);
  284.         artiexist[m] = TRUE;
  285.         return (otmp);
  286.     }
  287.     return ((struct obj *) 0);
  288. }
  289. # endif
  290.  
  291. int
  292. defends(adtyp, otmp)
  293. register int adtyp;
  294. register struct obj *otmp;
  295. {
  296.     register const struct artifact *weap;
  297.  
  298.     if(weap = get_artifact(otmp))
  299.         return(weap->defn.adtyp == adtyp);
  300.     return(0);
  301. }
  302.  
  303. #endif /* OVLB */
  304. #ifdef OVL1
  305.  
  306. STATIC_OVL int
  307. spec_applies(weap, ptr)
  308. register const struct artifact *weap;
  309. struct permonst *ptr;
  310. {
  311.     if(!(weap->spfx & (SPFX_DBONUS | SPFX_ATTK)))
  312.         return(0);
  313.  
  314.     if(weap->spfx & SPFX_DMONS)
  315.         return((ptr == &mons[(int)weap->mtype]));
  316.     else if(weap->spfx & SPFX_DCLAS)
  317.         return((weap->mtype == ptr->mlet));
  318.     else if(weap->spfx & SPFX_DFLAG1)
  319.         return((ptr->mflags1 & weap->mtype) != 0L);
  320.     else if(weap->spfx & SPFX_DFLAG2)
  321.         return((ptr->mflags2 & weap->mtype) != 0L);
  322.     else if(weap->spfx & SPFX_ATTK) {
  323.         switch(weap->attk.adtyp) {
  324.         case AD_FIRE:    return(!resists_fire(ptr));
  325.         case AD_COLD:    return(!resists_cold(ptr));
  326.         case AD_ELEC:    return(!resists_elec(ptr));
  327.         case AD_DRLI:    return(!resists_drli(ptr));
  328.         case AD_STON:    return(!resists_ston(ptr));
  329.         default:    impossible("Weird special attack for '%s'",
  330.                        weap->name);
  331.         }
  332.     }
  333.     return(0);
  334. }
  335.  
  336. int
  337. spec_abon(otmp, ptr)
  338. struct obj *otmp;
  339. struct permonst *ptr;
  340. {
  341.     register const struct artifact *weap;
  342.  
  343.     if((weap = get_artifact(otmp)))
  344.         if(spec_applies(weap, ptr))
  345.             return((weap->attk.damn) ? rnd((int)weap->attk.damn) : 0);
  346.     return(0);
  347. }
  348.  
  349. int
  350. spec_dbon(otmp, ptr, tmp)
  351. register struct obj *otmp;
  352. register struct permonst *ptr;
  353. register int    tmp;
  354. {
  355.     register const struct artifact *weap;
  356.  
  357.     if((weap = get_artifact(otmp)))
  358.         if(spec_applies(weap, ptr))
  359.             return((weap->attk.damd) ? rnd((int)weap->attk.damd) : tmp);
  360.     return(0);
  361. }
  362.  
  363. #endif /* OVL1 */
  364.  
  365. #endif /* NAMED_ITEMS */
  366.